<!DOCTYPE html>












  


<html class="theme-next gemini use-motion" lang="zh-CN">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2"/>
<meta name="theme-color" content="#222">












<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />






















<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=6.3.0" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=6.3.0">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=6.3.0">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=6.3.0">


  <link rel="mask-icon" href="/images/logo.svg?v=6.3.0" color="#222">









<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '6.3.0',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: false,
    fastclick: false,
    lazyload: false,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>


  




  <meta name="description" content="目录  文字描述 Dispatch Queue dispatch_sync&amp;amp;dispatch_async 创建的线程任务有四种执行方式 Dispatch Group  Dispatch Block  dispatch_after dispatch_apply dispatch_once dispatch_barrier_async dispatch_set_target_queue">
<meta property="og:type" content="article">
<meta property="og:title" content="gcd全解析">
<meta property="og:url" content="http://yoursite.com/2018/07/28/gcd全解析/index.html">
<meta property="og:site_name" content="Ray&#39;Zone">
<meta property="og:description" content="目录  文字描述 Dispatch Queue dispatch_sync&amp;amp;dispatch_async 创建的线程任务有四种执行方式 Dispatch Group  Dispatch Block  dispatch_after dispatch_apply dispatch_once dispatch_barrier_async dispatch_set_target_queue">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http://upload-images.jianshu.io/upload_images/147395-2c4f15f0c75ab698.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:updated_time" content="2018-07-28T14:27:53.322Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="gcd全解析">
<meta name="twitter:description" content="目录  文字描述 Dispatch Queue dispatch_sync&amp;amp;dispatch_async 创建的线程任务有四种执行方式 Dispatch Group  Dispatch Block  dispatch_after dispatch_apply dispatch_once dispatch_barrier_async dispatch_set_target_queue">
<meta name="twitter:image" content="http://upload-images.jianshu.io/upload_images/147395-2c4f15f0c75ab698.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">






  <link rel="canonical" href="http://yoursite.com/2018/07/28/gcd全解析/"/>



<script type="text/javascript" id="page.configurations">
  CONFIG.page = {
    sidebar: "",
  };
</script>

  <title>gcd全解析 | Ray'Zone</title>
  









  <noscript>
  <style type="text/css">
    .use-motion .motion-element,
    .use-motion .brand,
    .use-motion .menu-item,
    .sidebar-inner,
    .use-motion .post-block,
    .use-motion .pagination,
    .use-motion .comments,
    .use-motion .post-header,
    .use-motion .post-body,
    .use-motion .collection-title { opacity: initial; }

    .use-motion .logo,
    .use-motion .site-title,
    .use-motion .site-subtitle {
      opacity: initial;
      top: initial;
    }

    .use-motion {
      .logo-line-before i { left: initial; }
      .logo-line-after i { right: initial; }
    }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Ray'Zone</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
    
  </div>

  <div class="site-nav-toggle">
    <button aria-label="切换导航栏">
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>



<nav class="site-nav">
  
    <ul id="menu" class="menu">
      
        
        
        
          
          <li class="menu-item menu-item-home">
    <a href="/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-home"></i> <br />首页</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-categories">
    <a href="/categories/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-th"></i> <br />分类</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-about">
    <a href="/about/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-user"></i> <br />关于</a>
  </li>

      
      
    </ul>
  

  

  
</nav>



  



</div>
    </header>

    


    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          
            

          
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/07/28/gcd全解析/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Ray">
      <meta itemprop="description" content="恋恋不忘，必有回响">
      <meta itemprop="image" content="http://7xk5w6.com1.z0.glb.clouddn.com/WechatIMG1.jpeg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Ray'Zone">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">gcd全解析
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">

            
            
            

            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              

              
                
              

              <time title="创建时间：2018-07-28 21:47:50 / 修改时间：22:27:53" itemprop="dateCreated datePublished" datetime="2018-07-28T21:47:50+08:00">2018-07-28</time>
            

            
              

              
            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/iOS开发/" itemprop="url" rel="index"><span itemprop="name">iOS开发</span></a></span>

                
                
              
            </span>
          

          
            
          

          
          
             <span id="/2018/07/28/gcd全解析/" class="leancloud_visitors" data-flag-title="gcd全解析">
               <span class="post-meta-divider">|</span>
               <span class="post-meta-item-icon">
                 <i class="fa fa-eye"></i>
               </span>
               
                 <span class="post-meta-item-text">阅读次数：</span>
               
                 <span class="leancloud-visitors-count"></span>
             </span>
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <blockquote>
<p><strong>目录</strong></p>
<ol>
<li>文字描述</li>
<li>Dispatch Queue</li>
<li>dispatch_sync&amp;dispatch_async</li>
<li>创建的线程任务有四种执行方式</li>
<li>Dispatch Group </li>
<li>Dispatch Block </li>
<li>dispatch_after</li>
<li>dispatch_apply</li>
<li>dispatch_once</li>
<li>dispatch_barrier_async</li>
<li>dispatch_set_target_queue</li>
</ol>
</blockquote>
<h2 id="1-文字描述"><a href="#1-文字描述" class="headerlink" title="1. 文字描述"></a>1. 文字描述</h2><blockquote>
<p>GCD英文全称：Grand Central Dispatch 翻译就是 宏大的中央调度，是苹果开发的一种支持并行操作的机制,基于C语言，提供了非常多强大的函数</p>
</blockquote>
<p>在了解GCD并使用之前，必须要掌握四个名词：<strong>串行，并发，同步，异步</strong></p>
<h6 id="串行-Serial-："><a href="#串行-Serial-：" class="headerlink" title="串行(Serial)："></a>串行(Serial)：</h6><p>一个任务执行完, 再执行下一个任务</p>
<h6 id="并发-Concurrent-："><a href="#并发-Concurrent-：" class="headerlink" title="并发 (Concurrent)："></a>并发 (Concurrent)：</h6><p>多个任务同时执行(自动开启多个线程),只有在异步函数下才有效</p>
<h6 id="同步-Synchronous-："><a href="#同步-Synchronous-：" class="headerlink" title="同步(Synchronous)："></a>同步(Synchronous)：</h6><p>在当前线程中执行任务，不具备开启新线程的能力<br>提交的任务在执行完成后才会返回<br>同步函数: dispatch_sync()</p>
<h6 id="异步-Asynchronous-："><a href="#异步-Asynchronous-：" class="headerlink" title="异步 (Asynchronous)："></a>异步 (Asynchronous)：</h6><p>在新的线程中执行任务, 具备开启线程的能力<br>在新线程中执行任务，具备开启新线程的能力<br>提交的任务立刻返回，在后台队列中执行<br>异步函数: dispatch_async()</p>
<hr>
<h2 id="2-Dispatch-Queue"><a href="#2-Dispatch-Queue" class="headerlink" title="2. Dispatch Queue"></a>2. Dispatch Queue</h2><p>Dispatch Queue是执行处理的等待队列, 按照先进先出(FIFO, First-In-First-Out)的顺序进行任务处理.<br>开发者将需要执行的任务添加到合适的Dispatch Queue中即可，Dispatch Queue会根据任务添加的顺序先到先执行，其中有以下几种队列：</p>
<p>另外, 队列分两种, 一种是<strong>串行队列(Serial Dispatch Queue)</strong>, 一种是<strong>并行队列(Concurrent Dispatch Queue)</strong>.</p>
<table>
<thead>
<tr>
<th>Dispatch Queue的种类</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>Serial Dispatch Queue</td>
<td>等待现在执行中处理结束</td>
</tr>
<tr>
<td>Concurrent Dispatch Queue</td>
<td>不等待现在执行中处理结束</td>
</tr>
</tbody>
</table>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建一个串行队列</span></span><br><span class="line"><span class="keyword">dispatch_queue_t</span> serialQueue=dispatch_queue_create(<span class="string">"com.serial.queue"</span>, DISPATCH_QUEUE_SERIAL);</span><br><span class="line"></span><br><span class="line"><span class="comment">//创建一个并发队列</span></span><br><span class="line"><span class="keyword">dispatch_queue_t</span> concurrentQueue=dispatch_queue_create(<span class="string">"com.concurrent.queue"</span>, DISPATCH_QUEUE_CONCURRENT);</span><br><span class="line"></span><br><span class="line"><span class="comment">//第一个参数为队列名，第二个参数为队列类型，当然，第二个参数人如果写NULL，创建出来的也是一个串行队列。然后我们在异步线程来执行这个队列：</span></span><br></pre></td></tr></table></figure>
<p>另外系统为我们准备了两个队列</p>
<ul>
<li><h6 id="main-dispatch-queue"><a href="#main-dispatch-queue" class="headerlink" title="main dispatch queue"></a>main dispatch queue</h6><p>功能跟主线程一样，通过dispatch_get_main_queue()来获取，提交到main queue的任务实际上都是在主线程执行的，所以这是一个串行队列</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dispatch_queue_t<span class="built_in"> queue </span>= dispatch_get_main_queue();</span><br></pre></td></tr></table></figure>
</li>
<li><h6 id="global-dispatch-queues"><a href="#global-dispatch-queues" class="headerlink" title="global dispatch queues"></a>global dispatch queues</h6><p>系统给每个应用提供四个全局的并发队列，这四个队列分别有不同的优先级：高、默认、低以及后台，用户不能去创建全局队列，只能根据优先级去获取:</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dispatch_queue_t<span class="built_in"> queue </span> = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);</span><br></pre></td></tr></table></figure>
</li>
</ul>
<hr>
<h2 id="3-dispatch-sync-amp-dispatch-async"><a href="#3-dispatch-sync-amp-dispatch-async" class="headerlink" title="3. dispatch_sync&amp;dispatch_async"></a>3. dispatch_sync&amp;dispatch_async</h2><p>执行队列中任务的两种方式，<strong>dispatch_sync</strong>是同步任务，<strong>dispatch_async</strong>是异步任务</p>
<p>1.<strong>用同步的方式执行任务(同步：synchronization)</strong>， 只能在当前线程中执行任务，不具备开启新线程的能力<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">*  第一个参数：该任务所在的队列</span></span><br><span class="line"><span class="comment">*  第二个参数：该任务要做的事情</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">dispatch_sync(<span class="keyword">dispatch_queue_t</span> <span class="built_in">queue</span>, <span class="keyword">dispatch_block_t</span> block);</span><br></pre></td></tr></table></figure></p>
<ul>
<li><p>假如我指定的队列A是串行队列，则该队列中只能有一个线程，也就是说我放在队列A中的任务，所以必须得一个一个的执行。不仅如此，在上面我们还手动选择了在队列A中用同步的方式执行任务，这也限制了，队列中的任务只能一个一个执行。</p>
</li>
<li><p>假如我指定的队列A是并行队列，则该队列中可以开辟多个线程去执行任务，虽然如此，但由于我们在上面手动选择了在队列A中用同步的方式执行线程，所以队列A中的任务也只能一个一个去执行，<strong>不能开辟多线程同时执行</strong>。</p>
</li>
</ul>
<p>2.<strong>用异步的方式执行任务(异步：asynchronous)</strong>，可以在新的线程中执行任务，具备开启新线程的能力。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dispatch_async(<span class="keyword">dispatch_queue_t</span> <span class="built_in">queue</span>, <span class="keyword">dispatch_block_t</span> block);</span><br></pre></td></tr></table></figure>
<ul>
<li><p>假如此时我指定的队列B是并行队列，则表明该队列中可以存在多个线程，又因为我们采用的是异步的方式执行任务，所以在这个队列的任务可以实现同时运行。</p>
</li>
<li><p>假如此时我指定的队列B是串行队列，则表明该队列中，只能有一个线程，所以尽管我采用异步的方式执行任务，但该队列中的任务还是只能一个一个的运行。</p>
</li>
</ul>
<hr>
<h2 id="4-创建的线程任务有四种执行方式"><a href="#4-创建的线程任务有四种执行方式" class="headerlink" title="4. 创建的线程任务有四种执行方式"></a>4. 创建的线程任务有四种执行方式</h2><p><img src="http://upload-images.jianshu.io/upload_images/147395-2c4f15f0c75ab698.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br><strong>1. 串行队列同步执行任务</strong></p>
<ul>
<li>同步不具有开辟新线程的能力，不会开辟新的线程去执行任务，会在当前程序的主线程中执行任务。</li>
<li>按照串行的方式去执行任务</li>
</ul>
<figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">void</span>)syncSERIAL&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"star"</span>);</span><br><span class="line"><span class="comment">//不会开辟新的线程</span></span><br><span class="line"><span class="built_in">dispatch_queue_t</span> queue=dispatch_queue_create(<span class="string">"com.GCD_demo.www"</span>, DISPATCH_QUEUE_SERIAL);</span><br><span class="line"><span class="built_in">dispatch_sync</span>(queue, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"SERIAL_work_1 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_sync</span>(queue, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"SERIAL_work_2 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_sync</span>(queue, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"SERIAL_work_3 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"end"</span>);</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:08</span><span class="selector-pseudo">:09.695</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8196:1029563]</span> <span class="selector-tag">star</span></span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:08</span><span class="selector-pseudo">:09.696</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8196:1029563]</span> <span class="selector-tag">SERIAL_work_1</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:08</span><span class="selector-pseudo">:09.696</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8196:1029563]</span> <span class="selector-tag">SERIAL_work_2</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:08</span><span class="selector-pseudo">:09.696</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8196:1029563]</span> <span class="selector-tag">SERIAL_work_3</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:08</span><span class="selector-pseudo">:09.696</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8196:1029563]</span> <span class="selector-tag">end</span></span><br></pre></td></tr></table></figure></p>
<p><strong>由于是同步操作，不能开辟线程，所以都是在主线程并按照顺序执行</strong></p>
<p><strong>2.  串行队列异步执行任务</strong></p>
<ul>
<li>异步具有创建新线程的能力，会开辟新的线程去执行任务</li>
<li>按照串行的方式去执行任务</li>
</ul>
<figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">void</span>)asyncSERIAL&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"star"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//会开辟新的线程,但是是串行执行任务</span></span><br><span class="line"><span class="built_in">dispatch_queue_t</span> queue=dispatch_queue_create(<span class="string">"ki"</span>, DISPATCH_QUEUE_SERIAL);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">3</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"SERIAL_work_1 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">2</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"SERIAL_work_2 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"SERIAL_work_3 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"end"</span>);</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:09</span><span class="selector-pseudo">:58.494</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8213:1031268]</span> <span class="selector-tag">star</span></span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:09</span><span class="selector-pseudo">:58.495</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8213:1031268]</span> <span class="selector-tag">end</span></span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:10</span><span class="selector-pseudo">:01.496</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8213:1031315]</span> <span class="selector-tag">SERIAL_work_1</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:10</span><span class="selector-pseudo">:03.502</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8213:1031315]</span> <span class="selector-tag">SERIAL_work_2</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:10</span><span class="selector-pseudo">:03.502</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8213:1031315]</span> <span class="selector-tag">SERIAL_work_3</span></span><br></pre></td></tr></table></figure></p>
<p><strong>因为是异步操作，所以有个编号为2的子线程被开辟，但有因为是串行队列，所以只开辟了一个线程。最终造就了三个任务顺序执行。</strong></p>
<p><strong>3. 并行队列同步执行任务</strong></p>
<ul>
<li>同步不具有创建新线程的能力，不会开辟新的线程去执行任务，会在当前程序的主线程去执行任务</li>
<li>按照同步的方式去执行任务<figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">void</span>)syncCONCURRENT&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"star"</span>);</span><br><span class="line"><span class="comment">//不会开辟新的线程</span></span><br><span class="line"><span class="comment">//串行执行命令</span></span><br><span class="line"><span class="built_in">dispatch_queue_t</span> queue=dispatch_queue_create(<span class="string">"com.GCD_demo.www"</span>, DISPATCH_QUEUE_CONCURRENT);</span><br><span class="line"><span class="built_in">dispatch_sync</span>(queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">3</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"CONCURRENT_work_1 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_sync</span>(queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">2</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"CONCURRENT_work_2 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_sync</span>(queue, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"CONCURRENT_work_3 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"end"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:13</span><span class="selector-pseudo">:03.753</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8232:1033759]</span> <span class="selector-tag">star</span></span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:13</span><span class="selector-pseudo">:06.755</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8232:1033759]</span> <span class="selector-tag">CONCURRENT_work_1</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:13</span><span class="selector-pseudo">:08.756</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8232:1033759]</span> <span class="selector-tag">CONCURRENT_work_2</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:13</span><span class="selector-pseudo">:08.756</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8232:1033759]</span> <span class="selector-tag">CONCURRENT_work_3</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:13</span><span class="selector-pseudo">:08.757</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8232:1033759]</span> <span class="selector-tag">end</span></span><br></pre></td></tr></table></figure></p>
<p><strong>虽然并行队列决定了该队列中可以有多个线程，但由于是同步操作，不能开辟线程，所以还都是在主线程中按顺序执行。</strong></p>
<p><strong>4. 并发队列异步执行任务(常用)</strong></p>
<ul>
<li>异步具有创建新线程的能力，会开辟新的线程去执行任务，不会在当前程序的主线程去执行任务</li>
<li>按照并发的方式去执行任务<figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">void</span>)asyncCONCURRENT&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"star"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//一个队列 为 每个任务开辟一个线程</span></span><br><span class="line"><span class="built_in">dispatch_queue_t</span> queue=dispatch_queue_create(<span class="string">"com.GCD_demo.www"</span>, DISPATCH_QUEUE_CONCURRENT);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">3</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"CONCURRENT_work_1 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">2</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"CONCURRENT_work_2 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"CONCURRENT_work_3 "</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"end"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:18</span><span class="selector-pseudo">:26.768</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8256:1038143]</span> <span class="selector-tag">star</span></span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:18</span><span class="selector-pseudo">:26.768</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8256:1038143]</span> <span class="selector-tag">end</span></span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:18</span><span class="selector-pseudo">:26.769</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8256:1038192]</span> <span class="selector-tag">CONCURRENT_work_3</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:18</span><span class="selector-pseudo">:28.771</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8256:1038179]</span> <span class="selector-tag">CONCURRENT_work_2</span> </span><br><span class="line">2016<span class="selector-tag">-07-20</span> 20<span class="selector-pseudo">:18</span><span class="selector-pseudo">:29.773</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[8256:1038188]</span> <span class="selector-tag">CONCURRENT_work_1</span></span><br></pre></td></tr></table></figure></p>
<p><strong>并行队列可以里可以有多个线程，同步执行的方式又可以开辟多个线程，所以这里实现了多个线程并行执行。</strong></p>
<hr>
<h2 id="5-Dispatch-Group"><a href="#5-Dispatch-Group" class="headerlink" title="5. Dispatch Group"></a>5. Dispatch Group</h2><p>当我们想在gcd queue中所有的任务执行完毕之后做些特定事情的时候，也就是队列的同步问题，如果队列是串行的话，那将该操作最后添加到队列中即可，但如果队列是并行队列的话，这时候就可以利用dispatch_group来实现了，dispatch_group能很方便的解决同步的问题。dispatch_group_create可以创建一个group对象，然后可以添加block到该组里面，下面看下它的一些用法：</p>
<ul>
<li><strong>dispatch_group_notify</strong><br>是通过异步的方式通知，所以，不会阻塞线程<figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">-(void)asyncGroupNotify</span><br><span class="line">&#123;</span><br><span class="line">NSLog(@<span class="string">"star"</span>)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_group_t </span>group=<span class="keyword">dispatch_group_create();</span></span><br><span class="line"><span class="keyword">dispatch_queue_t </span>queue=<span class="keyword">dispatch_queue_create("com.GCD_demo.www", </span><span class="keyword">DISPATCH_QUEUE_CONCURRENT);</span></span><br><span class="line"><span class="keyword">dispatch_group_async(group, </span>queue, ^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">1</span>]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"group_work_1"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_group_async(group, </span>queue, ^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">6</span>]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"group_work_2"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_group_async(group, </span>queue, ^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">2</span>]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"group_work_3"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">dispatch_group_notify(group, </span>queue, ^&#123;</span><br><span class="line">NSLog(@<span class="string">"dispatch_group_Notify 结束"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>运行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:51</span><span class="selector-pseudo">:40.600</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9044:1162213]</span> <span class="selector-tag">star</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:51</span><span class="selector-pseudo">:41.605</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9044:1162359]</span> <span class="selector-tag">group_work_1</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:51</span><span class="selector-pseudo">:42.608</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9044:1162389]</span> <span class="selector-tag">group_work_3</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:51</span><span class="selector-pseudo">:46.603</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9044:1162349]</span> <span class="selector-tag">group_work_2</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:51</span><span class="selector-pseudo">:46.605</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9044:1162349]</span> <span class="selector-tag">dispatch_group_Notify</span> 结束</span><br></pre></td></tr></table></figure></p>
<ul>
<li><strong>dispatch_group_wait</strong><br>会阻塞当前线程，知道任务都完成时才会继续执行下面的代码</li>
</ul>
<figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">void</span>)asyncGroupWait</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"star"</span>);</span><br><span class="line">dispatch_group_t group=dispatch_group_create();</span><br><span class="line"><span class="built_in">dispatch_queue_t</span> queue=dispatch_queue_create(<span class="string">"com.GCD_demo.www"</span>, DISPATCH_QUEUE_CONCURRENT);</span><br><span class="line">dispatch_group_async(group, queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">1</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"group_work_1"</span>);</span><br><span class="line">&#125;);</span><br><span class="line">dispatch_group_async(group, queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">6</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"group_work_2"</span>);</span><br><span class="line">&#125;);</span><br><span class="line">dispatch_group_async(group, queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">2</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"group_work_3"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//在此设置了一个12秒的等待时间，如果group的执行结束没有到12秒那么就返回0</span></span><br><span class="line"><span class="comment">//如果执行group的执行时间超过了12秒，那么返回非0 数值，</span></span><br><span class="line"><span class="comment">//在使用dispatch_group_wait函数的时候，会阻塞当前线程，阻塞的时间 在wait函数时间值和当前group执行时间值取最小的。</span></span><br><span class="line"><span class="keyword">long</span> kk=dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, <span class="number">12</span> * <span class="built_in">NSEC_PER_SEC</span>));</span><br><span class="line"><span class="keyword">if</span>(kk==<span class="number">0</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"dispatch_group_wait 结果1"</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"dispatch_group_wait 结果2"</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:56</span><span class="selector-pseudo">:47.471</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9065:1165380]</span> <span class="selector-tag">star</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:56</span><span class="selector-pseudo">:48.472</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9065:1165494]</span> <span class="selector-tag">group_work_1</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:56</span><span class="selector-pseudo">:49.476</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9065:1165502]</span> <span class="selector-tag">group_work_3</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:56</span><span class="selector-pseudo">:53.475</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9065:1165485]</span> <span class="selector-tag">group_work_2</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 13<span class="selector-pseudo">:56</span><span class="selector-pseudo">:53.475</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9065:1165380]</span> <span class="selector-tag">dispatch_group_wait</span> 结果1</span><br></pre></td></tr></table></figure></p>
<ul>
<li><strong>dispatch_group_enter</strong>&amp;<strong>dispatch_group_leave</strong><br>假如我们不想使用dispatch_group_async异步的将任务丢到group中去执行，这时候就需要用到dispatch_group_enter跟dispatch_group_leave方法，这两个方法要配对出现，以下这两种方法是等价的：<figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">void</span>)asyncGroupEnter</span><br><span class="line">&#123;</span><br><span class="line"><span class="comment">// 群组－统一监控一组任务</span></span><br><span class="line">dispatch_group_t group = dispatch_group_create();</span><br><span class="line"></span><br><span class="line"><span class="built_in">dispatch_queue_t</span> queue = dispatch_get_global_queue(<span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 1&gt; 入组 -&gt; 之后的 block 会被 group 监听</span></span><br><span class="line"><span class="comment">// dispatch_group_enter 一定和 dispatch_group_leave 要配对出现</span></span><br><span class="line">dispatch_group_enter(group);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"dispatch_async_work1"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// block 的末尾，所有任务执行完毕后，添加一个出组</span></span><br><span class="line">dispatch_group_leave(group);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//  再次入组</span></span><br><span class="line">dispatch_group_enter(group);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, ^&#123;</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">6</span>];</span><br><span class="line"></span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"dispatch_async_work1"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// block 的末尾，所有任务执行完毕后，添加一个出组</span></span><br><span class="line">dispatch_group_leave(group);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 群组结束</span></span><br><span class="line">dispatch_group_notify(group, dispatch_get_main_queue(), ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"OVER"</span>);</span><br><span class="line">&#125;);  </span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"come here"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 15<span class="selector-pseudo">:21</span><span class="selector-pseudo">:40.707</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9256:1205427]</span> <span class="selector-tag">come</span> <span class="selector-tag">here</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 15<span class="selector-pseudo">:21</span><span class="selector-pseudo">:40.707</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9256:1205465]</span> <span class="selector-tag">dispatch_async_work1</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 15<span class="selector-pseudo">:21</span><span class="selector-pseudo">:46.709</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9256:1205460]</span> <span class="selector-tag">dispatch_async_work1</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 15<span class="selector-pseudo">:21</span><span class="selector-pseudo">:46.710</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9256:1205427]</span> <span class="selector-tag">OVER</span></span><br></pre></td></tr></table></figure></p>
<hr>
<p>##6. Dispatch Block<br>添加到gcd队列中执行的任务是以block的形式添加的，block封装了需要执行功能，block带来的开发效率提升就不说了，gcd跟block可以说是一对好基友，能够很好的配合使用。<br><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">-(void)dispatchBlock</span><br><span class="line">&#123;</span><br><span class="line">dispatch_queue_t<span class="built_in"> queue </span>= dispatch_queue_create(<span class="string">"com.GCD_demo.www"</span>, DISPATCH_QUEUE_SERIAL);</span><br><span class="line">dispatch_block_t <span class="attribute">block</span>=dispatch_block_create(0, ^&#123;</span><br><span class="line">NSLog(@<span class="string">"dispatchBlock_work"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">dispatch_sync(queue, block);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p><strong> 1.dispatch_block_wait</strong><br>当需要等待前面的任务执行完毕时，我们可以使用dispatch_block_wait这个接口，设置等待时间DISPATCH_TIME_FOREVER会一直等待直到前面的任务完成.用法跟dispatch_group_wait类似<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">void</span>)dispatchBlockWait</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">dispatch_queue_t</span> queue = dispatch_queue_create(<span class="string">"com.GCD_demo.www"</span>, DISPATCH_QUEUE_SERIAL);</span><br><span class="line">dispatch_block_t block = dispatch_block_create(<span class="number">0</span>, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"before sleep"</span>);</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">6</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"after sleep"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, block);</span><br><span class="line"><span class="comment">//等待前面的任务执行完毕</span></span><br><span class="line"><span class="keyword">long</span> kk=dispatch_block_wait(block, dispatch_time(DISPATCH_TIME_NOW, <span class="number">3</span> * <span class="built_in">NSEC_PER_SEC</span>));</span><br><span class="line"><span class="keyword">if</span>(kk==<span class="number">0</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"coutinue"</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"timeOut！！！"</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:28</span><span class="selector-pseudo">:38.313</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9533:1251011]</span> <span class="selector-tag">before</span> <span class="selector-tag">sleep</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:28</span><span class="selector-pseudo">:41.314</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9533:1250971]</span> <span class="selector-tag">timeOut</span>！！！</span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:28</span><span class="selector-pseudo">:44.318</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9533:1251011]</span> <span class="selector-tag">after</span> <span class="selector-tag">sleep</span></span><br></pre></td></tr></table></figure></p>
<p><strong> 2.dispatch_block_notify</strong><br>dispatch_block_notify当观察的某个block执行结束之后立刻通知提交另一特定的block到指定的queue中执行，该函数有三个参数，第一参数是需要观察的block，第二个参数是被通知block提交执行的queue，第三参数是当需要被通知执行的block<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">void</span>)dispatchBlockNotify</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">dispatch_queue_t</span> queue = dispatch_queue_create(<span class="string">"com.GCD_demo.www"</span>, DISPATCH_QUEUE_SERIAL);</span><br><span class="line">dispatch_block_t previousBlock = dispatch_block_create(<span class="number">0</span>, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"previousBlock begin"</span>);</span><br><span class="line">[<span class="built_in">NSThread</span> sleepForTimeInterval:<span class="number">2</span>];</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"previousBlock done"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">dispatch_async</span>(queue, previousBlock);</span><br><span class="line">dispatch_block_t notifyBlock = dispatch_block_create(<span class="number">0</span>, ^&#123;</span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"notifyBlock"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">//当previousBlock执行完毕后，提交notifyBlock到global queue中执行</span></span><br><span class="line">dispatch_block_notify(previousBlock, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, <span class="number">0</span>), notifyBlock);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:38</span><span class="selector-pseudo">:19.756</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9664:1261328]</span> <span class="selector-tag">previousBlock</span> <span class="selector-tag">begin</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:38</span><span class="selector-pseudo">:21.762</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9664:1261328]</span> <span class="selector-tag">previousBlock</span> <span class="selector-tag">done</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:38</span><span class="selector-pseudo">:21.762</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9664:1261329]</span> <span class="selector-tag">notifyBlock</span></span><br></pre></td></tr></table></figure></p>
<p><strong>3. dispatch_block_cancel</strong></p>
<p>可以取消提交到队列的block<br><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">-(void)<span class="keyword">dispatchBlockCancel</span></span><br><span class="line"><span class="keyword">&#123;</span></span><br><span class="line"><span class="keyword">dispatch_queue_t </span>queue = <span class="keyword">dispatch_queue_create("com.GCD_demo.www", </span><span class="keyword">DISPATCH_QUEUE_CONCURRENT);</span></span><br><span class="line"><span class="keyword">dispatch_block_t </span><span class="keyword">block1 </span>= <span class="keyword">dispatch_block_create(0, </span>^&#123;</span><br><span class="line">NSLog(@<span class="string">"block1 begin"</span>)<span class="comment">;</span></span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">1</span>]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"block1 done"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_block_t </span><span class="keyword">block2 </span>= <span class="keyword">dispatch_block_create(0, </span>^&#123;</span><br><span class="line">NSLog(@<span class="string">"block2 "</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_async(queue, </span><span class="keyword">block1);</span></span><br><span class="line"><span class="keyword">dispatch_async(queue, </span><span class="keyword">block2);</span></span><br><span class="line"><span class="keyword">dispatch_block_cancel(block2);</span></span><br><span class="line"><span class="keyword">&#125;</span></span><br></pre></td></tr></table></figure></p>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:50</span><span class="selector-pseudo">:28.140</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9723:1272259]</span> <span class="selector-tag">block1</span> <span class="selector-tag">begin</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:50</span><span class="selector-pseudo">:29.144</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9723:1272259]</span> <span class="selector-tag">block1</span> <span class="selector-tag">done</span></span><br></pre></td></tr></table></figure></p>
<hr>
<p>##7.dispatch_after<br>来延迟执行的GCD方法，因为在主线程中我们不能用sleep来延迟方法的调用，所以用它是最合适的，我们做一个简单的例子：<br><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">-(void)<span class="keyword">dispatchAfter</span></span><br><span class="line"><span class="keyword">&#123;</span></span><br><span class="line"><span class="keyword">NSLog(@"dispatchAfter_star");</span></span><br><span class="line"><span class="keyword">int64_t </span>time=<span class="number">2</span>*NSEC_PER_SEC<span class="comment">;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">dispatch_queue_t </span>mainQueue=<span class="keyword">dispatch_get_main_queue();</span></span><br><span class="line"><span class="keyword"></span></span><br><span class="line"><span class="keyword">for </span>(int i=<span class="number">0</span><span class="comment">; i&lt;5; i++) &#123;</span></span><br><span class="line"><span class="keyword">dispatch_time_t </span><span class="keyword">disTime=dispatch_time(DISPATCH_TIME_NOW, </span>time*i)<span class="comment">;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">dispatch_after(disTime, </span>mainQueue, ^&#123;</span><br><span class="line">NSLog(@<span class="string">"dispatchAfter_work"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:12</span><span class="selector-pseudo">:07.204</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9439:1237251]</span> <span class="selector-tag">dispatchAfter_star</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:12</span><span class="selector-pseudo">:07.211</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9439:1237251]</span> <span class="selector-tag">dispatchAfter_work</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:12</span><span class="selector-pseudo">:09.398</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9439:1237251]</span> <span class="selector-tag">dispatchAfter_work</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:12</span><span class="selector-pseudo">:11.205</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9439:1237251]</span> <span class="selector-tag">dispatchAfter_work</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:12</span><span class="selector-pseudo">:13.205</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9439:1237251]</span> <span class="selector-tag">dispatchAfter_work</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 16<span class="selector-pseudo">:12</span><span class="selector-pseudo">:15.205</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9439:1237251]</span> <span class="selector-tag">dispatchAfter_work</span></span><br></pre></td></tr></table></figure></p>
<hr>
<p>##8.dispatch_apply<br>dispatch_apply类似一个for循环，会在指定的dispatch queue中运行block任务n次，如果队列是并发队列，则会并发执行block任务，dispatch_apply是一个同步调用，block任务执行n次后才返回。<br><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">-(void)dispatchApply</span><br><span class="line">&#123;</span><br><span class="line">dispatch_queue_t<span class="built_in"> queue </span>= dispatch_queue_create(<span class="string">"com.GCD_demo.www"</span>, DISPATCH_QUEUE_CONCURRENT);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">dispatch_apply(6, queue, ^(size_t i) &#123;</span><br><span class="line">NSLog(@<span class="string">"do a job %zu times"</span>,i);</span><br><span class="line"></span><br><span class="line">&#125;);</span><br><span class="line">NSLog(@<span class="string">"go on"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:04</span><span class="selector-pseudo">:54.558</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9831:1284549]</span> <span class="selector-tag">do</span> <span class="selector-tag">a</span> <span class="selector-tag">job</span> 0 <span class="selector-tag">times</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:04</span><span class="selector-pseudo">:54.564</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9831:1284583]</span> <span class="selector-tag">do</span> <span class="selector-tag">a</span> <span class="selector-tag">job</span> 1 <span class="selector-tag">times</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:04</span><span class="selector-pseudo">:54.564</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9831:1284589]</span> <span class="selector-tag">do</span> <span class="selector-tag">a</span> <span class="selector-tag">job</span> 2 <span class="selector-tag">times</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:04</span><span class="selector-pseudo">:54.564</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9831:1284593]</span> <span class="selector-tag">do</span> <span class="selector-tag">a</span> <span class="selector-tag">job</span> 3 <span class="selector-tag">times</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:04</span><span class="selector-pseudo">:54.564</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9831:1284549]</span> <span class="selector-tag">do</span> <span class="selector-tag">a</span> <span class="selector-tag">job</span> 4 <span class="selector-tag">times</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:04</span><span class="selector-pseudo">:54.564</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9831:1284583]</span> <span class="selector-tag">do</span> <span class="selector-tag">a</span> <span class="selector-tag">job</span> 5 <span class="selector-tag">times</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:04</span><span class="selector-pseudo">:54.566</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9831:1284549]</span> <span class="selector-tag">go</span> <span class="selector-tag">on</span></span><br></pre></td></tr></table></figure></p>
<hr>
<p>##9.dispatch_once<br>整个程序运行中只会执行一次，使用dispatch_once可以简化代码并且彻底保证线程安全，开发者根本无须担心加锁或者同步。所有问题都由GCD在底层处理。由于每次调用时都必须使用完全相同的标记，所以标记要声明成static。所以用在单例模式上是最好的<br><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">static SingletonTimer * instance;</span><br><span class="line">static dispatch_once_t onceToken;</span><br><span class="line">dispatch_once(&amp;onceToken, ^&#123;</span><br><span class="line">instance = [[SingletonTimer alloc] init];</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">return instance;</span><br></pre></td></tr></table></figure></p>
<hr>
<p>##10. dispatch_barrier_async<br>dispatch_barrier_async用于等待前面的任务执行完毕后自己才执行，而它后面的任务需等待它完成之后才执行。一个典型的例子就是数据的读写，通常为了防止文件读写导致冲突，我们会创建一个串行的队列，所有的文件操作都是通过这个队列来执行，比如FMDB，这样就可以避免读写冲突。不过其实这样效率是有提升的空间的，当没有更新数据时，读操作其实是可以并行进行的，而写操作需要串行的执行</p>
<figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">-(void)<span class="keyword">diapatchBarrier</span></span><br><span class="line"><span class="keyword">&#123;</span></span><br><span class="line"><span class="keyword">dispatch_queue_t </span>queue = <span class="keyword">dispatch_queue_create("com.GCD_demo.www", </span><span class="keyword">DISPATCH_QUEUE_CONCURRENT);</span></span><br><span class="line"><span class="keyword"></span></span><br><span class="line"><span class="keyword">dispatch_async(queue, </span>^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">6</span>]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"dispatch_async_work1"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_async(queue, </span>^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">2</span>]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"dispatch_async_work2"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_barrier_async(queue, </span>^&#123;</span><br><span class="line">NSLog(@<span class="string">"dispatch_async_work3"</span>)<span class="comment">;</span></span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">1</span>]<span class="comment">;</span></span><br><span class="line"></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_async(queue, </span>^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">1</span>]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"dispatch_async_work4"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 15<span class="selector-pseudo">:54</span><span class="selector-pseudo">:24.402</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9354:1225160]</span> <span class="selector-tag">dispatch_async_work2</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 15<span class="selector-pseudo">:54</span><span class="selector-pseudo">:28.403</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9354:1225152]</span> <span class="selector-tag">dispatch_async_work1</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 15<span class="selector-pseudo">:54</span><span class="selector-pseudo">:28.403</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9354:1225152]</span> <span class="selector-tag">dispatch_async_work3</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 15<span class="selector-pseudo">:54</span><span class="selector-pseudo">:30.412</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9354:1225152]</span> <span class="selector-tag">dispatch_async_work4</span></span><br></pre></td></tr></table></figure></p>
<hr>
<p>##11.dispatch_set_target_queue</p>
<p>1.系统的Global Queue是可以指定优先级的，那我们可以用到dispatch_set_target_queue这个方法来指定自己创建队列的优先级<br><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">-(void)<span class="keyword">DispatchSet</span></span><br><span class="line"><span class="keyword">&#123;</span></span><br><span class="line"><span class="keyword">dispatch_queue_t </span>serialDiapatchQueue=<span class="keyword">dispatch_queue_create("com.GCD_demo.www", </span><span class="keyword">DISPATCH_QUEUE_SERIAL);</span></span><br><span class="line"><span class="keyword">dispatch_queue_t </span><span class="keyword">dispatchgetglobalqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, </span><span class="number">0</span>)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_set_target_queue(serialDiapatchQueue, </span><span class="keyword">dispatchgetglobalqueue);</span></span><br><span class="line"><span class="keyword">dispatch_async(serialDiapatchQueue, </span>^&#123;</span><br><span class="line">NSLog(@<span class="string">"我优先级低，先让让"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, </span><span class="number">0</span>), ^&#123;</span><br><span class="line">NSLog(@<span class="string">"我优先级高,我先block"</span>)<span class="comment">;</span></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:22</span><span class="selector-pseudo">:02.512</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9902:1297023]</span> 我优先级高,我先<span class="selector-tag">block</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:22</span><span class="selector-pseudo">:02.512</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[9902:1297035]</span> 我优先级低，先让让</span><br></pre></td></tr></table></figure></p>
<p>2.dispatch_set_target_queue除了能用来设置队列的优先级之外，还能够创建队列的层次体系，当我们想让不同队列中的任务同步的执行时，我们可以创建一个串行队列，然后将这些队列的target指向新创建的队列即可<br><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">-(void)<span class="keyword">dispatchSet2</span></span><br><span class="line"><span class="keyword">&#123;</span></span><br><span class="line"><span class="keyword">dispatch_queue_t </span>targetQueue = <span class="keyword">dispatch_queue_create("target_queue", </span><span class="keyword">DISPATCH_QUEUE_SERIAL);</span></span><br><span class="line"><span class="keyword">dispatch_queue_t </span>queue1 = <span class="keyword">dispatch_queue_create("queue1", </span><span class="keyword">DISPATCH_QUEUE_SERIAL);</span></span><br><span class="line"><span class="keyword">dispatch_queue_t </span>queue2 = <span class="keyword">dispatch_queue_create("queue2", </span><span class="keyword">DISPATCH_QUEUE_CONCURRENT);</span></span><br><span class="line"><span class="keyword"></span></span><br><span class="line"><span class="keyword"></span></span><br><span class="line"><span class="keyword">dispatch_set_target_queue(queue1, </span>targetQueue)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_set_target_queue(queue2, </span>targetQueue)<span class="comment">;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">dispatch_async(queue1, </span>^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">3</span>.f]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"do job1"</span>)<span class="comment">;</span></span><br><span class="line"></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_async(queue2, </span>^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">2</span>.f]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"do job2"</span>)<span class="comment">;</span></span><br><span class="line"></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line"><span class="keyword">dispatch_async(queue2, </span>^&#123;</span><br><span class="line">[NSThread sleepForTimeInterval:<span class="number">1</span>.f]<span class="comment">;</span></span><br><span class="line">NSLog(@<span class="string">"do job3"</span>)<span class="comment">;</span></span><br><span class="line"></span><br><span class="line">&#125;)<span class="comment">;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>执行结果<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:28</span><span class="selector-pseudo">:54.327</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[10043:1303853]</span> <span class="selector-tag">do</span> <span class="selector-tag">job1</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:28</span><span class="selector-pseudo">:56.331</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[10043:1303853]</span> <span class="selector-tag">do</span> <span class="selector-tag">job2</span></span><br><span class="line">2016<span class="selector-tag">-07-21</span> 17<span class="selector-pseudo">:28</span><span class="selector-pseudo">:57.335</span> <span class="selector-tag">GCD_Demo</span><span class="selector-attr">[10043:1303853]</span> <span class="selector-tag">do</span> <span class="selector-tag">job3</span></span><br></pre></td></tr></table></figure></p>

      
    </div>

    

    
    
    

    

    

    

    <footer class="post-footer">
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/07/28/test3/" rel="next" title="test3">
                <i class="fa fa-chevron-left"></i> test3
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2018/07/28/test2/" rel="prev" title="test2">
                test2 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>


  </div>


          </div>
          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="http://7xk5w6.com1.z0.glb.clouddn.com/WechatIMG1.jpeg"
                alt="Ray" />
            
              <p class="site-author-name" itemprop="name">Ray</p>
              <p class="site-description motion-element" itemprop="description">恋恋不忘，必有回响</p>
          </div>

          
            <nav class="site-state motion-element">
              
                <div class="site-state-item site-state-posts">
                
                  <a href="/archives">
                
                    <span class="site-state-item-count">4</span>
                    <span class="site-state-item-name">日志</span>
                  </a>
                </div>
              

              
                
                
                <div class="site-state-item site-state-categories">
                  <a href="/categories/index.html">
                    
                    
                      
                    
                      
                    
                      
                    
                      
                    
                    <span class="site-state-item-count">4</span>
                    <span class="site-state-item-name">分类</span>
                  </a>
                </div>
              

              
            </nav>
          

          

          
            <div class="links-of-author motion-element">
              
                <span class="links-of-author-item">
                  <a href="https://weibo.com/lirui43" target="_blank" title="微博"><i class="fa fa-fw fa-weibo"></i>微博</a>
                  
                </span>
              
                <span class="links-of-author-item">
                  <a href="https://twitter.com/yourname" target="_blank" title="微信"><i class="fa fa-fw fa-wechat"></i>微信</a>
                  
                </span>
              
                <span class="links-of-author-item">
                  <a href="https://gitee.com/romitlee" target="_blank" title="码云"><i class="fa fa-fw fa-code"></i>码云</a>
                  
                </span>
              
                <span class="links-of-author-item">
                  <a href="https://www.jianshu.com/u/c622f0c0f667" target="_blank" title="简书"><i class="fa fa-fw fa-book"></i>简书</a>
                  
                </span>
              
            </div>
          

          
          

          
          

          
            
          
          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-文字描述"><span class="nav-text">1. 文字描述</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#串行-Serial-："><span class="nav-text">串行(Serial)：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#并发-Concurrent-："><span class="nav-text">并发 (Concurrent)：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#同步-Synchronous-："><span class="nav-text">同步(Synchronous)：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#异步-Asynchronous-："><span class="nav-text">异步 (Asynchronous)：</span></a></li></ol></li></ol></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-Dispatch-Queue"><span class="nav-text">2. Dispatch Queue</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#main-dispatch-queue"><span class="nav-text">main dispatch queue</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#global-dispatch-queues"><span class="nav-text">global dispatch queues</span></a></li></ol></li></ol></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-dispatch-sync-amp-dispatch-async"><span class="nav-text">3. dispatch_sync&amp;dispatch_async</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-创建的线程任务有四种执行方式"><span class="nav-text">4. 创建的线程任务有四种执行方式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-Dispatch-Group"><span class="nav-text">5. Dispatch Group</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; 2015-2018 &mdash; <span itemprop="copyrightYear">2018</span>
  <span class="with-love" id="animate">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Ray</span>

  

  
</div>











        








        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    
	
    

    
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>














  













  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/canvas-nest/canvas-nest.min.js"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=6.3.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=6.3.0"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=6.3.0"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=6.3.0"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=6.3.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=6.3.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=6.3.0"></script>



  



  










  





  

  
  <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script>
  <script>AV.initialize("p9ajbfN88SQEnNsuCI3oyec2-gzGzoHsz", "mVeTY6U5FUBH6DeSbelQar5w");</script>
  <script>
    function showTime(Counter) {
      var query = new AV.Query(Counter);
      var entries = [];
      var $visitors = $(".leancloud_visitors");

      $visitors.each(function () {
        entries.push( $(this).attr("id").trim() );
      });

      query.containedIn('url', entries);
      query.find()
        .done(function (results) {
          var COUNT_CONTAINER_REF = '.leancloud-visitors-count';

          if (results.length === 0) {
            $visitors.find(COUNT_CONTAINER_REF).text(0);
            return;
          }

          for (var i = 0; i < results.length; i++) {
            var item = results[i];
            var url = item.get('url');
            var time = item.get('time');
            var element = document.getElementById(url);

            $(element).find(COUNT_CONTAINER_REF).text(time);
          }
          for(var i = 0; i < entries.length; i++) {
            var url = entries[i];
            var element = document.getElementById(url);
            var countSpan = $(element).find(COUNT_CONTAINER_REF);
            if( countSpan.text() == '') {
              countSpan.text(0);
            }
          }
        })
        .fail(function (object, error) {
          console.log("Error: " + error.code + " " + error.message);
        });
    }

    function addCount(Counter) {
      var $visitors = $(".leancloud_visitors");
      var url = $visitors.attr('id').trim();
      var title = $visitors.attr('data-flag-title').trim();
      var query = new AV.Query(Counter);

      query.equalTo("url", url);
      query.find({
        success: function(results) {
          if (results.length > 0) {
            var counter = results[0];
            counter.fetchWhenSave(true);
            counter.increment("time");
            
            counter.save(null, {
              success: function(counter) {
                
                  var $element = $(document.getElementById(url));
                  $element.find('.leancloud-visitors-count').text(counter.get('time'));
                
              },
              error: function(counter, error) {
                console.log('Failed to save Visitor num, with error message: ' + error.message);
              }
            });
          } else {
            
              var $element = $(document.getElementById(url));
              $element.find('.leancloud-visitors-count').text('Counter not initialized! See more at console err msg.');
              console.error('ATTENTION! LeanCloud counter has security bug, see here how to solve it: https://github.com/theme-next/hexo-leancloud-counter-security. \n But you also can use LeanCloud without security, by set \'security\' option to \'false\'.');
            
          }
        },
        error: function(error) {
          console.log('Error:' + error.code + " " + error.message);
        }
      });
    }

    $(function() {
      var Counter = AV.Object.extend("Counter");
      if ($('.leancloud_visitors').length == 1) {
        addCount(Counter);
      } else if ($('.post-title-link').length > 1) {
        showTime(Counter);
      }
    });
  </script>



  

  

  

  
  

  

  

  

  

  

  
     <!-- custom analytics part create by xiamo -->
<script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
<script>AV.initialize("p9ajbfN88SQEnNsuCI3oyec2-gzGzoHsz", "mVeTY6U5FUBH6DeSbelQar5w");</script>
<script>
function showTime(Counter) {
	var query = new AV.Query(Counter);
	$(".leancloud_visitors").each(function() {
		var url = $(this).attr("id").trim();
		query.equalTo("url", url);
		query.find({
			success: function(results) {
				if (results.length == 0) {
					var content = $(document.getElementById(url)).text() + ': 0';
					$(document.getElementById(url)).text(content);
					return;
				}
				for (var i = 0; i < results.length; i++) {
					var object = results[i];
					var content = $(document.getElementById(url)).text() + ': ' + object.get('time');
					$(document.getElementById(url)).text(content);
				}
			},
			error: function(object, error) {
				console.log("Error: " + error.code + " " + error.message);
			}
		});

	});
}

function addCount(Counter) {
	var Counter = AV.Object.extend("Counter");
	url = $(".leancloud_visitors").attr('id').trim();
	title = $(".leancloud_visitors").attr('data-flag-title').trim();
	var query = new AV.Query(Counter);
	query.equalTo("url", url);
	query.find({
		success: function(results) {
			if (results.length > 0) {
				var counter = results[0];
				counter.fetchWhenSave(true);
				counter.increment("time");
				counter.save(null, {
					success: function(counter) {
						var content = $(document.getElementById(url)).text() + ': ' + counter.get('time');
						$(document.getElementById(url)).text(content);
					},
					error: function(counter, error) {
						console.log('Failed to save Visitor num, with error message: ' + error.message);
					}
				});
			} else {
				var newcounter = new Counter();
				newcounter.set("title", title);
				newcounter.set("url", url);
				newcounter.set("time", 1);
				newcounter.save(null, {
					success: function(newcounter) {
					    console.log("newcounter.get('time')="+newcounter.get('time'));
						var content = $(document.getElementById(url)).text() + ': ' + newcounter.get('time');
						$(document.getElementById(url)).text(content);
					},
					error: function(newcounter, error) {
						console.log('Failed to create');
					}
				});
			}
		},
		error: function(error) {
			console.log('Error:' + error.code + " " + error.message);
		}
	});
}
$(function() {
	var Counter = AV.Object.extend("Counter");
	if ($('.leancloud_visitors').length == 1) {
		addCount(Counter);
	} else if ($('.post-title-link').length > 1) {
		showTime(Counter);
	}
});
</script>
  
</body>
</html>
